/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package guzik.lukasz.snpmanager.servlets;

import SnpDbEntities.Category;
import SnpDbEntities.Snippet;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;

/**
 *
 * @author Łukasz 'byku' Guzik
 */
class ExtendedTreeModel extends DefaultTreeModel
{
    ExtendedTreeModel(TreeNode root)
    {
	super(root);
    }

    @Override
    public void insertNodeInto(MutableTreeNode newChild, MutableTreeNode parent, int index)
    {
	Object objectToInsert = ((DefaultMutableTreeNode) newChild).getUserObject();
	Object testObject;
	int lastChildIndex = parent.getChildCount() - 1;

	if(lastChildIndex < 0)
	{
	    super.insertNodeInto(newChild, parent, 0);
	    return;
	}

	index = (lastChildIndex) / 2;
	while(true)
	{
	    testObject = ((DefaultMutableTreeNode) parent.getChildAt(index)).getUserObject();
	    if(shouldbeBefore(objectToInsert, testObject))
	    {
		if(index <= 0)
		{
		    index = 0;
		    break;
		}

		testObject = ((DefaultMutableTreeNode) parent.getChildAt(index - 1)).getUserObject();
		if(!shouldbeBefore(objectToInsert, testObject))
		{
		    break;
		}

		index = index / 2;
	    } else
	    {
		if(index >= lastChildIndex)
		{
		    index = lastChildIndex + 1;
		    break;
		}

		index++;
		testObject = ((DefaultMutableTreeNode) parent.getChildAt(index)).getUserObject();
		if(shouldbeBefore(objectToInsert, testObject))
		{
		    break;
		}

		index += (lastChildIndex - index) / 2;
	    }
	}

	super.insertNodeInto(newChild, parent, index);
    }

    private boolean shouldbeBefore(Object objectToInsert, Object testObject)
    {
	String insertName;
	String testName;

	if(objectToInsert instanceof Category && testObject instanceof Category)
	{
	    insertName = ((Category) objectToInsert).getName();
	    testName = ((Category) testObject).getName();

	    if(insertName.compareToIgnoreCase(testName) < 0)
	    {
		return true;
	    }
	} else if(objectToInsert instanceof Snippet && testObject instanceof Snippet)
	{
	    insertName = ((Snippet) objectToInsert).getName();
	    testName = ((Snippet) testObject).getName();

	    if(insertName.compareToIgnoreCase(testName) < 0)
	    {
		return true;
	    }
	} else if(objectToInsert instanceof Category && testObject instanceof Snippet)
	{
	    return true;
	}

	return false;
    }
}
